package com.me.common.util;

import org.apache.commons.lang3.time.DurationFormatUtils;

import java.time.Duration;
import java.time.temporal.Temporal;

/**
 * 时间间隔计算工具类
 *
 * @author ME
 * @date 2021/2/20
 */
public class DurationUtils {

    /**
     * 自定义 Duration 使出格式，格式为 “n天 m小时 x分钟”
     */
    private static final String DURATION_FORMAT_BY_MINUTES = "d天H小时m分钟";

    /**
     * 自定义 Duration 使出格式，格式为 “n天 m小时 x分钟 y秒”
     */
    private static final String DURATION_FORMAT_BY_SECONDS = "d天H小时m分钟s秒";

    /**
     * 计算时间差，以分钟为单位，向上取整
     *
     * @param startInclusive    停车入场时间
     * @param endInclusive      停车离场时间
     * @return  整分钟的时间差
     */
    public static Duration computeIntervalTimeByMinutes(Temporal startInclusive, Temporal endInclusive) {
        return DurationUtils.computeIntervalTimeByMinutes(Duration.between(startInclusive, endInclusive));
    }

    /**
     * 计算时间差，以分钟为单位，向上取整
     *
     * @param duration  时间差
     * @return  整分钟的时间差
     */
    public static Duration computeIntervalTimeByMinutes(Duration duration) {
        if (duration.toNanos() <= 0) {
            duration = Duration.ofDays(1).plus(duration);
        }
        // 时间差取整分钟
        if (duration.toNanos() % LocalTimeUtils.NANOS_PER_MINUTE > 0) {
            duration = Duration.ofMinutes(duration.toMinutes() + 1);
        }
        return duration;
    }

    /**
     * 计算时间差，以秒为单位，向上取整
     *
     * @param startInclusive    停车入场时间
     * @param endInclusive      停车离场时间
     * @return  整分钟的时间差
     */
    public static Duration computeIntervalTimeBySeconds(Temporal startInclusive, Temporal endInclusive) {
        return DurationUtils.computeIntervalTimeBySeconds(Duration.between(startInclusive, endInclusive));
    }

    /**
     * 计算时间差，以秒为单位，向上取整
     *
     * @param duration  时间差
     * @return  整秒的时间差
     */
    public static Duration computeIntervalTimeBySeconds(Duration duration) {
        if (duration.toNanos() <= 0) {
            duration = Duration.ofDays(1).plus(duration);
        }
        // 时间差取整秒
        if (duration.toNanos() % LocalTimeUtils.NANOS_PER_SECOND > 0) {
            duration = Duration.ofSeconds(duration.getSeconds() + 1);
        }
        return duration;
    }

    /**
     * 以 “n天 m小时 x分钟 y秒” 的格式返回停车时长（分钟向上取整）
     *
     * @return  多少天多少小时多少分钟
     */
    public static String formatDurationByMinutes(Duration duration) {
        if (duration.toNanos() <= 0) {
            duration = Duration.ofDays(1).plus(duration);
        }
        long durationMillis = duration.toMillis();
        // 时间差取整秒
        if (duration.toNanos() % LocalTimeUtils.NANOS_PER_MINUTE > 0) {
            durationMillis += LocalTimeUtils.NANOS_PER_MINUTE;
        }

        return DurationFormatUtils.formatDuration(durationMillis, DURATION_FORMAT_BY_MINUTES,false);
    }

    /**
     * 以 “n天 m小时 x分钟 y秒” 的格式返回停车时长（分钟向上取整）
     *
     * @return  多少天多少小时多少分钟
     */
    public static String formatDurationBySeconds(Duration duration) {
        if (duration.toNanos() <= 0) {
            duration = Duration.ofDays(1).plus(duration);
        }
        long durationMillis = duration.toMillis();
        // 时间差取整秒
        if (duration.toNanos() % LocalTimeUtils.NANOS_PER_SECOND > 0) {
            durationMillis += LocalTimeUtils.MILLIS_PER_SECOND;
        }

        return DurationFormatUtils.formatDuration(durationMillis, DURATION_FORMAT_BY_SECONDS,false);
    }

    public static void main(String[] args) {
        // 1天0小时0分钟
        System.out.println(formatDurationByMinutes(Duration.ofDays(1)));
        // 1天0小时0分钟0秒
        System.out.println(formatDurationBySeconds(Duration.ofDays(1)));
    }

}
